package dev.langchain4j.model.chat.response;

import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.model.chat.StreamingChatModel;

/**
 * Represents a handler for a {@link StreamingChatModel} response.
 *
 * @see StreamingChatModel
 */
public interface StreamingChatResponseHandler {

    /**
     * Invoked each time the model generates a partial response (usually a single token) in a textual response.
     * If the model decides to execute a tool instead, this method will not be invoked;
     * {@link #onCompleteResponse} will be invoked instead.
     *
     * @param partialResponse The partial response (usually a single token), which is a part of the complete response.
     */
    void onPartialResponse(String partialResponse);

    /**
     * TODO
     * TODO this callback is called as soon as partial tool is available
     * TODO can be called multiple times
     * TODO can be called for multiple tool executions,
     * TODO give example of how this and other callback can be called
     * @param index TODO
     * @param partialToolExecutionRequest TODO
     */
    default void onPartialToolExecutionRequest(int index, ToolExecutionRequest partialToolExecutionRequest) {
    }

    /**
     * TODO
     * TODO this callback is called as soon as a single tool execution request is complete
     * TODO can be called multiple times
     * @param index TODO
     * @param completeToolExecutionRequest TODO
     */
    default void onCompleteToolExecutionRequest(int index, ToolExecutionRequest completeToolExecutionRequest) {
    }

    /**
     * Invoked when the model has finished streaming a response.
     * If the model requests the execution of one or multiple tools,
     * this can be accessed via {@link ChatResponse#aiMessage()} -> {@link AiMessage#toolExecutionRequests()}.
     *
     * @param completeResponse The complete response generated by the model.
     *                         For textual responses, it contains all tokens from {@link #onPartialResponse} concatenated.
     */
    void onCompleteResponse(ChatResponse completeResponse);

    /**
     * This method is invoked when an error occurs during streaming.
     *
     * @param error The error that occurred
     */
    void onError(Throwable error);
}
